﻿using CinemaMaestro.ViewModels;
using CinemaMaestro.WindowsApplication.EndPoints;
using MetroFramework;
using MetroFramework.Controls;
using MetroFramework.Forms;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace CinemaMaestro.WindowsApplication.Room
{
    public partial class RoomsForm : MetroForm
    {
        private RoomEndPoints endPoints;
        private CinemaViewModel cinema;
        private List<RoomViewModel> allRooms;
        private MetroTile[] seats;

        public RoomsForm(HttpClient client, CinemaViewModel cinema)
        {
            this.endPoints = new RoomEndPoints(client);
            this.cinema = cinema;
            this.seats = new MetroTile[100];

            InitializeComponent();
            PopulateRoomsListView();

            deleteButton.Enabled = false;
            updateButton.Enabled = false;
        }

        private async void PopulateRoomsListView()
        {
            roomsListView.Items.Clear();
            try
            {
                List<RoomViewModel> rooms = await endPoints.GetAllRoomsForCinemaAsync(cinema.Id);
                foreach (var room in rooms)
                {
                    var item = new ListViewItem();
                    item.Text = room.Id.ToString();
                    item.SubItems.Add(room.Name);
                    item.SubItems.Add(room.Capacity.ToString());
                    roomsListView.Items.Add(item);
                }
                allRooms = rooms;           
            }
            catch
            {
                MetroMessageBox.Show(this, "Cannot retrieve rooms!", String.Empty, MessageBoxButtons.OK, MessageBoxIcon.Hand);
            }
            SelectAllSeats();
        }

        private void clearButton_Click(object sender, EventArgs e)
        {
            nameTextBox.Text = String.Empty;
            roomsListView.SelectedIndices.Clear();
            deleteButton.Enabled = false;
            updateButton.Enabled = false;
            createButton.Enabled = true;
            SelectAllSeats();
        }

        private async void createButton_Click(object sender, EventArgs e)
        {
            if (ValidateRoom())
            {
                try
                {
                    var room = new RoomViewModel
                    { 
                        Name = nameTextBox.Text,
                        Capacity = GetRoomCapacity(),
                        Seats = GetRoomLayout(),
                        Cinema = cinema
                    };
                    await endPoints.CreateRoomAsync(room);
                }
                catch
                {
                    MetroMessageBox.Show(this, "Cannot create room!", String.Empty, MessageBoxButtons.OK, MessageBoxIcon.Hand);
                }
                finally
                {
                    PopulateRoomsListView();
                    nameTextBox.Text = String.Empty;
                }         
            }           
        }

        private void roomsListView_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (roomsListView.SelectedItems.Count == 1)
            {
                deleteButton.Enabled = true;
                updateButton.Enabled = true;
                createButton.Enabled = false;
                nameTextBox.Text = roomsListView.SelectedItems[0].SubItems[1].Text;
                int roomId = Int32.Parse(roomsListView.SelectedItems[0].SubItems[0].Text);
                RoomViewModel room = allRooms.First(x => x.Id == roomId);
                ShowAvailableSeats(room);
            }
        }

        private async void updateButton_Click(object sender, EventArgs e)
        {
            
            deleteButton.Enabled = false;
            updateButton.Enabled = false;   
            if (ValidateRoom())
            {
                try
                {
                    int selectedId = Int32.Parse(roomsListView.SelectedItems[0].SubItems[0].Text);
                    var room = new RoomViewModel
                    {
                        Id = selectedId,
                        Name = nameTextBox.Text,
                        Capacity = GetRoomCapacity(),
                        Seats = GetRoomLayout(),
                        Cinema = cinema
                    };
                    await endPoints.UpdateRoomAsync(room);
                }
                catch
                {
                    MetroMessageBox.Show(this, "Cannot update room!", String.Empty, MessageBoxButtons.OK, MessageBoxIcon.Hand);
                }
                finally
                {
                    PopulateRoomsListView();
                    roomsListView.SelectedIndices.Clear();
                    nameTextBox.Text = String.Empty;
                    createButton.Enabled = true;
                }   
            }          
        }

        private void RoomsForm_MouseDown(object sender, MouseEventArgs e)
        {
            roomsListView.SelectedIndices.Clear();
            deleteButton.Enabled = false;
            updateButton.Enabled = false;
            createButton.Enabled = true;
            nameTextBox.Text = String.Empty;
            SelectAllSeats();
        }

        private async void deleteButton_Click(object sender, EventArgs e)
        {
            try
            {
                deleteButton.Enabled = false;
                updateButton.Enabled = false;
                int selectedId = Int32.Parse(roomsListView.SelectedItems[0].SubItems[0].Text);
                await endPoints.DeleteRoomAsync(selectedId);
            }
            catch
            {
                MetroMessageBox.Show(this, "Cannot delete room!", String.Empty, MessageBoxButtons.OK, MessageBoxIcon.Hand);
            }
            finally
            {
                PopulateRoomsListView();
                roomsListView.SelectedIndices.Clear();
                nameTextBox.Text = String.Empty;
                createButton.Enabled = true;
            }           
        }

        private bool ValidateRoom()
        {
            if (nameTextBox.Text == String.Empty)
            {
                MetroMessageBox.Show(this, "Please provide a name for the Room!", String.Empty, MessageBoxButtons.OK, MessageBoxIcon.Hand);
                return false;
            }                    
            return true;
        }

        private void RoomsForm_Load(object sender, EventArgs e)
        {
            for (int y = 0; y < 10; y++)
            {
                for (int x = 0; x < 10; x++)
                {
                    MetroTile tile = new MetroTile();
                    tile.Left = 400 + x * 35;
                    tile.Top = 50 + y * 35;
                    tile.Width = 30;
                    tile.Height = 30;
                    tile.UseCustomBackColor = true;
                    tile.BackColor = Color.LightGreen;
                    tile.Name = "Seat:" + y + "-" + x;
                    tile.Click += (sendr, args) => ChangeSelected(tile);
                    this.seats[y*10 + x] = tile;
                    this.Controls.Add(tile);
                }
            }
        }

        private void ChangeSelected(MetroTile tile) 
        {
            if (tile.BackColor == Color.LightGray)
            {
                tile.BackColor = Color.LightGreen;
            }
            else
            {
                tile.BackColor = Color.LightGray;
            }
        }

        private string GetRoomLayout()
        {
            string layout = String.Empty;
            for (int y = 0; y < 10; y++)
            {
                for (int x = 0; x < 10; x++)
                {
                    var currentSeat = seats[y*10 + x];
                    if (currentSeat.BackColor == Color.LightGreen)
                    {
                        layout += "a";
                    }
                    else
                    {
                        layout += "_";
                    }
                }
                layout += ",";
            }
            layout = layout.Substring(0, layout.Length - 1);
            return layout;
        }

        private void ShowAvailableSeats(RoomViewModel room)
        {
            string[] rows = room.Seats.Split(',');
            for (int i = 0; i < rows.Length; i++)
            {
                for (int j = 0; j < rows[i].Length; j++)
                {
                    if (rows[i][j] == 'a')
                    {
                        seats[i * 10 + j].BackColor = Color.LightGreen;
                    }
                    else
                    {
                        seats[i * 10 + j].BackColor = Color.LightGray;
                    }
                }
            }
        }

        private void SelectAllSeats()
        {
            for (int i = 0; i < seats.Length; i++)
            {
                seats[i].BackColor = Color.LightGreen;
            }
        }

        private int GetRoomCapacity()
        {
            int capacity = 0;
            for (int i = 0; i < seats.Length; i++)
            {
                if (seats[i].BackColor == Color.LightGreen)
                {
                    capacity++;
                }               
            }
            return capacity;
        }
    }
}
